package com.mygame.components

import com.almasb.fxgl.dsl.FXGL
import com.almasb.fxgl.dsl.components.HealthIntComponent
import com.almasb.fxgl.dsl.getGameWorld
import com.almasb.fxgl.entity.Entity
import com.almasb.fxgl.entity.SpawnData
import com.almasb.fxgl.entity.component.Component
import com.almasb.fxgl.entity.state.EntityState
import com.almasb.fxgl.entity.state.StateComponent
import com.mygame.*
import com.mygame.manager.TimerManager
import javafx.geometry.Point2D
import javafx.scene.input.KeyCode
import javafx.scene.paint.Color
import javafx.util.Duration

class PlayerControllerComponent : Component() {
    private var stateComponent: StateComponent? = null
    private var comboComponent: ComboComponent? = null
    private lateinit var jumpPoint: Point2D
    private var isJumping = false
    private var jumpSpeed = -500.0
    private val gravity = 1000.0
    private var jumpCount = 0
    private val MAX_JUMP_COUNT = 1


    private val SPEED = 100.0 // 移动速度，单位：像素/秒
    private var shootDir = Dir.RIGHT
    private var tpf = 0.0
    private lateinit var walls: List<Entity>
    override fun onAdded() {
        super.onAdded()
        stateComponent = entity.getComponent(StateComponent::class.java)
        comboComponent = entity.getComponent(ComboComponent::class.java)
        walls = getGameWorld().getEntitiesByType(EType.WALL)
    }

    fun up() {
        move(Dir.UP, -90.0, -SPEED * tpf, true)
        comboComponent?.addInputKeys(KeyCode.UP.name)
    }

    fun down() {
        move(Dir.DOWN, 90.0, SPEED * tpf, true)
        comboComponent?.addInputKeys(KeyCode.DOWN.name)
    }

    fun left() {
        move(Dir.LEFT, -180.0, -SPEED * tpf, false)
        comboComponent?.addInputKeys(KeyCode.LEFT.name)
    }

    fun right() {
        move(Dir.RIGHT, 0.0, SPEED * tpf, false)
        comboComponent?.addInputKeys(KeyCode.RIGHT.name)
    }

    fun move(dir: Dir, angle: Double, moveSpeed: Double, isYDir: Boolean = true) {
        shootDir = dir
        stateComponent?.run {
            if (currentState == JUMP_ATTACK || currentState == ATTACK) {
                return
            }
        }

        var isCanMove = true
        for (wall in walls) {
            when (dir) {
                Dir.UP -> {
                    if (wall.center.y + wall.height / 2 < entity.center.y - entity.height / 2
                        && entity.distanceBBox(wall) < 2
                    ) {
                        isCanMove = false
                        //println("↑撞墙了 e:${entity.center.y - entity.height / 2} w:${wall.center.y + wall.height / 2}")
                        break
                    }
                }

                Dir.DOWN -> {
                    if (wall.center.y - wall.height / 2 > entity.center.y + entity.height / 2
                        && entity.distanceBBox(wall) < 2
                    ) {
                        isCanMove = false
                        //println("↓撞墙了 e:${entity.center.y + entity.height / 2} w:${wall.center.y - wall.height / 2}")
                        break
                    }
                }

                Dir.LEFT -> {
                    entity.scaleX = -1.0
                    if ((wall.center.x + wall.width / 2) < (entity.center.x - entity.width / 2)
                        && entity.distanceBBox(wall) < 2
                    ) {
                        //println("←撞墙了 e:${entity.center.x - entity.width / 2} w:${wall.center.x + wall.width / 2}")
                        isCanMove = false
                        break
                    }
                }

                Dir.RIGHT -> {
                    entity.scaleX = 1.0
                    if (wall.center.x - wall.width / 2 > entity.center.x + entity.width / 2
                        && entity.distanceBBox(wall) < 2
                    ) {
                        //println("→撞墙了 e:${entity.center.x + entity.width / 2} w:${wall.center.x - wall.width / 2}")
                        isCanMove = false
                        break
                    }
                }
            }
            isCanMove = true
        }
        if (isCanMove) {
            stateComponent?.changeState(RUN)
            if (isYDir) {
                entity.translateY(moveSpeed)
            } else {
                entity.translateX(moveSpeed)
            }
        }
    }

    fun idle() {
        stateComponent?.run {
            if (currentState == ATTACK
                || currentState == JUMP_ATTACK
                || currentState == SKILL1
            ) {
                return
            }
            changeState(IDLE)
        }
    }

    fun attack() {
        if (stateComponent?.changeAttackState(ATTACK) == true) {
            attackSuccessful(ATTACK)
        }
    }

    private fun attackSuccessful(state: EntityState) {
        //println("player.POSITION: ${entity.center}")
        val enemyList: Iterable<Entity> = getGameWorld().entities.filter {
            it.type == EType.ENEMY && it.center.distance(entity.center) < entity.width
        }
        val iterator = enemyList.iterator()
        while (iterator.hasNext()) {
            val enemy = iterator.next()
            //println("enemy.position: ${enemy.position} ${enemy.type}  距离${enemy.center.distance(entity.center)} ${entity.width / 2}")
            val hpEntity = enemy.properties.getObject<Entity>(Const.HP_ENTITY)
            val hpComponent = hpEntity.getComponent(HealthIntComponent::class.java)
            val point = when (state) {
                ATTACK -> -10
                JUMP_ATTACK -> -20
                else -> 0
            }
            hpComponent.changePoint(point)
            println("攻击敌人${point}HP 剩下: ${hpComponent.value}HP")
            if (hpComponent.value <= 0) {
                enemy.removeComponent(StateComponent::class.java)
                enemy.opacity = 0.5
                hpEntity.removeFromWorld()
                FXGL.getGameTimer().runAtInterval({
                    enemy.removeFromWorld()
                }, Duration.seconds(1.0))
            }
        }
    }

    fun jump() {
        if (stateComponent?.changeAttackState(JUMP_ATTACK) == true) {
            if (!isJumping && jumpCount < MAX_JUMP_COUNT) {
                jumpPoint = entity.position
                // 如果角色没有在跳跃中，并且跳跃次数没有超过最大值，开始跳跃
                isJumping = true
                jumpSpeed = -150.0
                jumpCount++
            }
            attackSuccessful(JUMP_ATTACK)
        }
    }

    private fun updateJumping() {
        if (isJumping) {
            // 在跳跃过程中，每一帧都更新角色的位置
            val y = entity.position.y
            val newY = y + jumpSpeed * tpf
            entity.setPosition(entity.position.x, newY)
            jumpSpeed += gravity * tpf
            //println("jumpSpeed=$jumpSpeed  newY=$newY  entity.position.y=${entity.position.y}")
            // 如果角色已经落地，停止跳跃
            if (jumpSpeed >= 150.0) {
                isJumping = false
                jumpCount = 0
                entity.setPosition(entity.position.x, jumpPoint.y)
            }
        }
    }

    //射击子弹
    fun skill1() {
        stateComponent?.changeAttackState(SKILL1)
        val r = 20.0
        spawn(
            EType.BULLET,
            SpawnData(entity.center.x - r, entity.center.y - r)
                .put(Const.RADIUS, r)
                .put(Const.DIR, shootDir.value)
                .put(Const.SPEED, 500.0)
                .put(Const.COLOR, Color.BLACK)
        )
    }

    fun clickShoot(vararg isLongShoot: Boolean) {
        //点击坐标点
        val clickPoint = Point2D(FXGL.getInput().mouseXWorld, FXGL.getInput().mouseYWorld)
    }

    override fun onUpdate(tpf: Double) {
        this.tpf = tpf
        updateJumping()

    }

}